home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / demo / demosrc / d_wavelet.pro < prev    next >
Text File  |  1997-07-08  |  50KB  |  1,538 lines

  1. ;$Id: d_wavelet.pro,v 1.23 1997/04/25 22:19:33 tremblay Exp $
  2. ;
  3. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ;  FILE:
  8. ;       d_wavelet.pro
  9. ;
  10. ;  CALLING SEQUENCE: d_wavelet
  11. ;
  12. ;  PURPOSE:
  13. ;       This example demonstrates the wavelets orthogonal functions
  14. ;
  15. ;  MAJOR TOPICS: Plotting and data analysis
  16. ;
  17. ;  CATEGORY:
  18. ;       IDL 5.0
  19. ;
  20. ;  INTERNAL FUNCTIONS and PROCEDURES:
  21. ;       fun wv_cutoff               -  Returns a threshold value
  22. ;       fun decimate                -  Set values within threshold limits
  23. ;       pro get_wavelet_basis       -  Compute the wavelet basis
  24. ;       fun adjust_size             -  Adjust data size
  25. ;       fun in_range                -  Set values within a give n range
  26. ;       pro no_compressed_image     -  Handle the no compressed image state
  27. ;       pro reset_plot              -  Reset the plots
  28. ;       pro Update_plot             -  Redraw the plots
  29. ;       pro new_percentage          -  Set to a new percentage (slider)
  30. ;       pro move_line               -  Move the plot line
  31. ;       pro moveSlider              -  Update slider value
  32. ;       pro got_new_image           -  Display the image
  33. ;       pro sensitize               -  Sensitize a widget
  34. ;       pro ChangeFilename          -  Update the title
  35. ;       pro erase_original          -  Erase the original image
  36. ;       pro erase_secondary         -  Erase the secondary image
  37. ;       pro data_input              -  Load a new data set
  38. ;       pro do_compression          -  Compute and display the compressed image
  39. ;       pro new_coeff               -  Handle the new coefficients
  40. ;       pro waveletTool_Event       -  Event handler
  41. ;       pro wavelet_Cleanup         -  Cleanup
  42. ;       pro d_wavelet                 -  Main procedure
  43. ;
  44. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  45. ;       pro getdata2                -  Read new data
  46. ;       wavelet.txt
  47. ;       wavelet.tip
  48. ;       abnorm1.dat
  49. ;       convec.dat
  50. ;       ctscan.dat
  51. ;       head.dat
  52. ;       hurric.dat
  53. ;       m51.dat
  54. ;       nyny.dat
  55. ;       sunflare.dat
  56. ;       venus_1.dat
  57. ;       venus_2.dat
  58. ;       venus_e.dat
  59. ;       worldelv.dat
  60. ;
  61. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  62. ;
  63. ;  NAMED STRUCTURES:
  64. ;       none.
  65. ;
  66. ;  COMMON BLOCS:
  67. ;       none.
  68. ;
  69. ;  MODIFICATION HISTORY:
  70. ;       95,   DS   - Written.
  71. ;       11/95,   DAT     - Modified for IDL 5.0 demo
  72. ;-
  73. ;---------------------------------------------------------------------  
  74. ;
  75. ;  PURPOSE
  76. ;       Return array of threshold value versus (% decimation * 10.)
  77. ;       For example, to get cutoff value for decimation of 60%,
  78. ;    use cutoff(60 * 10).
  79. ; Inputs:
  80. ;    Wavelet = array containing wavelet transform.
  81. ; Outputs:
  82. ;    Wvlog = log10 of wavelet transform (elements less than 10^(-4)
  83. ;        are set to 10^(-4).
  84. ;    Cutoff = 1001 element array containing threshold value versus
  85. ;        % decimation.
  86. ;
  87.  
  88. ;+
  89. ; NAME:
  90. ;    GetData2
  91. ; PURPOSE:
  92. ;    Retrieves a data file from the images directory in the main IDL
  93. ;    directory.  The file can be specified when calling the routine
  94. ;    or the file can be chosen by the user with a widget that lets them
  95. ;    make the selection.
  96. ; CATEGORY:
  97. ;    Widgets
  98. ; CALLING SEQUENCE:
  99. ;    GetData2, NEWDATA
  100. ; KEYWORD PARAMETERS:
  101. ;    ASSOC_IT = When set, this keyword forces the routine to return
  102. ;        an associated variable instead of a standard IDL variable.  
  103. ;        This is more efficient when loading animations for instance
  104. ;        as it removes the need to create two copies of the data
  105. ;        in memory (one for the animation, one for the load data).
  106. ;    DESCRIPTION = This keyword returns the description of the data
  107. ;        selected by the GetData routine (NEWDATA).
  108. ;    DIMENSIONS = This keyword returns the dimensions of the data
  109. ;        selected by the GetData routine.  These dimensions 
  110. ;        are the dimensions of the NEWDATA variable.
  111. ;    FILENAME = The name of the file that is to be selected from the
  112. ;        images subdirectory.  If this keyword is set, no user 
  113. ;        selection widget is created.
  114. ;    OFILENAME = name of file selected.
  115. ;    ONE_DIM = This keyword is set when the routine is to consider
  116. ;        one dimensional data from the data contained in the
  117. ;        images subdirectory.
  118. ;    TWO_DIM = This keyword is set when the routine is to consider
  119. ;        two dimensional data from the data contained in the
  120. ;        images subdirectory.  When searching for two dimensional
  121. ;        data, this routine will use the first slice of any 
  122. ;        three dimensional data that it encounters.
  123. ;    THREE_DIM = This keyword is set when the routine is to consider
  124. ;        three dimensional data from the data contained in the
  125. ;        images subdirectory.
  126. ;    TITLE = The string that will appear in the title portion
  127. ;        of the data selection widget.  If not specified, the
  128. ;        title will be "Please Select Data".
  129. ; OUTPUTS:
  130. ;    NEWDATA = the variable that is to be filled with the new data.
  131. ; COMMON BLOCKS:
  132. ;    GF - maintains which selection was made when using the data
  133. ;        selection widget.
  134. ; SIDE EFFECTS:
  135. ;    Desensitizes all the other widgets and is modal in behavior.  It 
  136. ;    forces the user to make a selection before proceeding with other 
  137. ;    widget functions.
  138. ; RESTRICTIONS:
  139. ;    Getdat2 must find the subdirectory called examples/dataimages of
  140. ;       the main IDL directory(IDL_DIR) and the directory must contain a
  141. ;       file called data.txt that describes the contents of the directory.
  142. ; PROCEDURE:
  143. ;    If the FILENAME keyword was not set, determine the file name using
  144. ;    a widget that lets the user make a selection from the data.txt file
  145. ;    and then open that file, read the data, dimensions, and description,
  146. ;    and return the data.
  147. ; MODIFICATION HISTORY:
  148. ;    Written by Steve Richards,    Dec, 1990
  149. ;       Modified by DAT, renamed getData2, add group keyword, 2/97
  150. ;-
  151. ;---------------------------------------------------------------------
  152. ;
  153. ;  PURPOSE  : Event handler
  154. ;
  155. pro GetData2_event, $
  156.     event              ; IN: event structure.
  157.  
  158.     COMMON GF, selection
  159.  
  160.     WIDGET_CONTROL, event.id, GET_UVALUE=selected
  161.  
  162.     case selected of
  163.         "FILELST": begin
  164.         WIDGET_CONTROL, event.top, SENSITIVE=0
  165.         WIDGET_CONTROL, event.top, /DESTROY
  166.         selection = event.index + 1
  167.         end    ;  of FILELST
  168.  
  169.         "CANCEL": WIDGET_CONTROL, event.top, /DESTROY
  170.     endcase
  171.  
  172. end    ;   of GetData_event 
  173.  
  174.  
  175. ;---------------------------------------------------------------------
  176. ;
  177. ;  PURPOSE  : Main procedure.
  178. ;    Retrieves a data file from the images directory in the main IDL
  179. ;    directory.  The file can be specified when calling the routine
  180. ;    or the file can be chosen by the user with a widget that lets them
  181. ;    make the selection.
  182. ;
  183. pro GetData2, $
  184.     NEWDATA, $                    ; OUT: new data set
  185.     GROUP=group, $                ; IN: (opt) group leader identifer.
  186.     DESCRIPTION = DESCRIPTION, $  ; OUT:  (opt)Data set description.
  187.     DIMENSIONS = DIMENSIONS, $    ; OUT: (opt) dimension of the data set
  188.     ONE_DIM = ONE_DIM, $          ; IN: (opt) Routine will consider 1-D data.
  189.     TWO_DIM = TWO_DIM, $          ; IN: (opt) Routine will consider 2-D data.
  190.     THREE_DIM = THREE_DIM, $      ; IN: (opt) Routine will consider 3-D data.
  191.     TITLE = TITLE, $              ; IN: (opt) Selection window title.
  192.     FILENAME = FILENAME, $        ; IN: File name of the data set.
  193.     OFILENAME = OFILENAME, $      ; OUT: (opt) output file name.
  194.     ASSOC_IT = ASSOC_IT           ; IN: (opt) routine returns an associate 
  195.                                   ;     variable instead of IDL variable. 
  196.  
  197.     COMMON GF, selection
  198.  
  199.     ;  For demo 5, the image files are located in the same directory
  200.     ;  tnan this procedure. Therefore, the data path is set to ' ' .
  201.     ;
  202.     datapath = filepath('', SUBDIR=['examples','data'])
  203.  
  204.     ;  Initialize working variables.
  205.     ;
  206.     name = ''
  207.     dim = LONARR(3)
  208.     des = ''
  209.     del = ''
  210.     numfiles = 0L
  211.     ONE_MASK = 1
  212.     TWO_MASK = 2
  213.     THREE_MASK = 4
  214.  
  215.     NEWDATA = 0
  216.     DESCRIPTION = 0
  217.     DIMENSIONS = 0
  218.  
  219.     if (KEYWORD_SET(FILENAME)) then begin
  220.         OPENR, unit, datapath + "data.txt", /GET_LUN
  221.         READF, unit, numfiles
  222.         if (numfiles NE 0) then begin
  223.             goodindex = 0
  224.             nameindex = 0
  225.  
  226.             while((nameindex LT (numfiles)) AND (goodindex EQ 0)) do begin
  227.                 READF, unit, name, dim, des, del
  228.                 if (name EQ FILENAME) then goodindex = 1
  229.                 if (del NE '*') then MESSAGE, $
  230.                     "* delimiter not found in data.txt"
  231.             endwhile
  232.  
  233.             FREE_LUN, unit
  234.  
  235.             if (goodindex NE 0) then begin
  236.             ofilename = filename
  237.                 OPENR, unit, datapath + FILENAME, /GET_LUN, /BLOCK
  238.  
  239.                 if (KEYWORD_SET(ASSOC_IT)) then begin
  240.                 NEWDATA = ASSOC(unit, BYTARR(dim(0),dim(1)))
  241.                 endif else begin
  242.                 NEWDATA = bytarr(dim(0), dim(1), dim(2))
  243.                 READU, unit, NEWDATA
  244.                     FREE_LUN, unit
  245.                 endelse
  246.  
  247.                 DESCRIPTION = des
  248.                 DIMENSIONS = dim
  249.             endif
  250.         endif
  251.     endif else if ((XRegistered("GetData2") EQ 0)) then begin
  252.  
  253.         FILTER = 0
  254.  
  255.         if (KEYWORD_SET(ONE_DIM)) then begin
  256.             FILTER = FILTER OR ONE_MASK
  257.         endif
  258.  
  259.         if (KEYWORD_SET(TWO_DIM)) then begin
  260.             FILTER = FILTER OR TWO_MASK OR THREE_MASK
  261.         endif
  262.  
  263.         if (KEYWORD_SET(THREE_DIM)) then begin
  264.             FILTER = FILTER OR THREE_MASK
  265.         endif
  266.  
  267.         if ((FILTER EQ 0)) then begin
  268.             FILTER = ONE_MASK + TWO_MASK + THREE_MASK
  269.         endif
  270.  
  271.         OPENR, unit, datapath + "data.txt", /GET_LUN
  272.         READF, unit, numfiles
  273.         if (numfiles NE 0) then begin
  274.             names = STRARR(numfiles)
  275.             descriptions = STRARR(numfiles)
  276.             dimensions = LONARR(3,numfiles)
  277.             goodindex = 0
  278.  
  279.             for nameindex = 0, numfiles - 1 do begin
  280.                 READF, unit, name, dim, des, del
  281.                 TEMPFILT = 0
  282.                 if (DIM(0) GT 1) then  TEMPFILT = ONE_MASK
  283.                 if (DIM(1) GT 1) then  TEMPFILT = TWO_MASK
  284.                 if (DIM(2) GT 1) then  TEMPFILT = THREE_MASK
  285.  
  286.                 if ((TEMPFILT AND FILTER) NE 0) then begin
  287.                     names(goodindex) = name
  288.                     dimensions(*,goodindex) = dim
  289.                     descriptions(goodindex) = des
  290.                     goodindex = goodindex + 1
  291.                 endif
  292.  
  293.                 if (del NE '*') then begin
  294.                     MESSAGE, "* delimiter not found in data.txt"
  295.                 endif
  296.  
  297.             endfor
  298.  
  299.             FREE_LUN, unit
  300.  
  301.             neworder = SORT(names(0:goodindex-1))
  302.             names = names(neworder)
  303.             descriptions = descriptions(neworder)
  304.             dimensions = dimensions(*,neworder)
  305.  
  306.             filler = "........................................"
  307.             fullnames = STRARR(goodindex)
  308.  
  309.             for i = 0, goodindex - 1 do begin
  310.                 dimstring = STRING(dimensions(*,i), $
  311.                     FORMAT = '("[",I0.3,", ",I0.3,", ",I0.3,"]")')
  312.                 length = STRLEN(names(i))
  313.                 lengthdim = STRLEN(dimstring)
  314.                 fullnames(i) = descriptions(i)
  315. ;      fullnames(i) = names(i) + $
  316. ;        STRMID(filler, 0, 30-length) + $
  317. ;        dimstring + $
  318. ;        STRMID(filler, 0, 30-lengthdim) + $
  319. ;        descriptions(i)
  320.             endfor
  321.  
  322.             if (NOT(KEYWORD_SET(TITLE))) then TITLE =  "Please Select Data"
  323.  
  324. ;    font = '*fixed*'   ;It seems to be impossible to find
  325. ;        a simple font on all servers.
  326.  
  327.             if (NOT(KEYWORD_SET(group))) then begin
  328.  
  329.                 loadbase = WIDGET_BASE(TITLE = TITLE, $
  330.                     /COLUMN, $
  331.                     XPAD = 50, $
  332.                     YPAD = 50, $
  333.                     SPACE = 20)
  334.             endif else begin
  335.                 loadbase = WIDGET_BASE(TITLE = TITLE, $
  336.                     GROUP_LEADER=group, /MODAL, $
  337.                     /COLUMN, $
  338.                     XPAD = 50, $
  339.                     YPAD = 50, $
  340.                     SPACE = 20)
  341.             endelse
  342.  
  343.                 loadbox = WIDGET_BASE(loadbase, $
  344.                     /COLUMN, $
  345.                     /FRAME, $
  346.                     SPACE=10)
  347.  
  348.                     loadlist = WIDGET_LIST(loadbox, $
  349.                         VALUE=fullnames, $
  350.                         UVALUE="FILELST", $
  351.                         YSIZE=10)
  352.  
  353.                 loadcancel = WIDGET_BUTTON(loadbase, $
  354.                     VALUE="Cancel", UVALUE="CANCEL")
  355.  
  356.         WIDGET_CONTROL, loadbase, /REALIZE
  357.   
  358.         selection = 0
  359.     
  360.         XMANAGER, "GetData2", loadbase 
  361.  
  362.         if (selection NE 0) then begin
  363.  
  364.             if ((NOT(KEYWORD_SET(THREE_DIM))) AND $
  365.                 (dimensions(2,selection-1) NE 1)) then $
  366.                 dimensions(2,selection-1) = 1
  367.  
  368.                 OPENR, unit, datapath + $
  369.                     names(selection - 1), /GET_LUN, /BLOCK
  370.                 ofilename = names(selection - 1)
  371.  
  372.                 if (KEYWORD_SET(ASSOC_IT))  then begin
  373.                 NEWDATA = ASSOC(unit, $
  374.                         BYTARR(dimensions(0, selection-1), $
  375.                         dimensions(1, selection-1)))
  376.                 endif else begin
  377.                 NEWDATA = BYTARR(dimensions(0, selection - 1), $
  378.                         dimensions(1, selection - 1), $
  379.                         dimensions(2, selection - 1))
  380.                 READU, unit, NEWDATA
  381.                 FREE_LUN, unit
  382.                 endelse
  383.  
  384.                 DESCRIPTION = descriptions(selection - 1)
  385.                 DIMENSIONS = dimensions(*,selection - 1)
  386.  
  387.             endif    ;  of keyword set three_dim
  388.         endif     ;   of selection NE 0
  389.     endif     ;  of keyword set filename.
  390.  
  391. end           ;  of GETDATA2
  392.  
  393.  
  394. ;---------------------------------------------------------------------
  395. ;
  396. ;  PURPOSE  : Compute the cutoff paramater.
  397. ;
  398. function WV_CUTOFF, $
  399.     wavelet         ; IN: wavelet coefficients.
  400.  
  401.     lowthr = 4         ; Consider only values over 10-lowthr
  402.     nhist = 1000     ; Number of histogram bins
  403.     nbins = 1000     ; Number of returned bins
  404.  
  405.     wvlog = alog10(abs(wavelet) > (10.0^(-lowthr))) + lowthr
  406.     wlmin = min(wvlog, MAX = wlmax)
  407.     bins = (wlmax - wlmin) / nhist
  408.     h = histogram(wvlog, min = wlmin, max = wlmax, binsize = bins) / $
  409.     float(n_elements(wvlog))
  410.     for i=1, nhist-1 do h(i) = h(i) + h(i-1)    ;Cumulative integral
  411.  
  412.     ;  This plus 1 for maximum value.
  413.     ;
  414.     cutoff = FLTARR(nbins+1)
  415.     j = 0
  416.     for i=1, nbins-1 do begin
  417.         t = float(i) / nbins
  418.         while (h(j) lt t) and (j lt nhist) do j = j + 1
  419.         cutoff(i) = j
  420.     endfor
  421.     cutoff = 10.0 ^ (cutoff * (wlmax/nhist) - lowthr)
  422.  
  423.     ;  Cutoff 1000 must hold the max value of the array
  424.     ;
  425.     cutoff(1000) = max(abs(wavelet))
  426.  
  427.     RETURN, cutoff
  428.  
  429. end
  430.  
  431. ;---------------------------------------------------------------------  
  432. ;
  433. ;   PURPOSE : Set the data to zero when below threshold value.
  434. ;
  435. function DECIMATE, original, threshold
  436.         new = original
  437.     d = where(abs(new) le threshold, count)     
  438.  
  439.     ;  If d=-1 then there is noplace like that   
  440.     ;
  441.     if (count GT 0) then new(d) = 0.0     
  442.     return, new
  443. end
  444.  
  445. ;---------------------------------------------------------------------  
  446. ;
  447. ;   PURPOSE : Clamp and scale input data and then display.
  448. ;             Assumes display is set to desired window
  449. ;
  450. pro demo_wvlt_tv, input
  451.     input = input > 0
  452.     input = input < 255
  453.     TVSCL, input
  454. end     
  455. ;---------------------------------------------------------------------  
  456. ;
  457. ;   PURPOSE : Compute the wavelet basis.
  458. ;
  459. pro Get_Wavelet_Basis, $
  460.     UVAL     ; IN: uval structure     
  461.  
  462.     ;  Given our uncompressed array     
  463.     ;  and coefficients, get a new     
  464.     ;  wavelet basis for the image     
  465.     ;
  466.     WIDGET_CONTROL, /HOURGLASS
  467.     UVAL.WVLT_IMG = NR_WTN(UVAL.ORIG_IMG, UVAL.COEFFS)
  468.   
  469.     UVAL.THRESHARRAY = WV_CUTOFF(UVAL.WVLT_IMG)
  470.  
  471.     ;  Now we need to tv the image of the
  472.     ;  undecimated and decimated wavelet bases
  473.     ;
  474.     WSET, UVAL.ID_WAVE1
  475.     demo_wvlt_tv, CONGRID (UVAL.WVLT_IMG, 200, 200)
  476.           
  477.     ;  Now we need to create the new plot
  478.     ;
  479.     Percent_Plot, UVAL
  480.     Reset_Plot, UVAL
  481. end     
  482.  
  483. ;---------------------------------------------------------------------  
  484. ;
  485. ;   PURPOSE : Adjust the viewwing area size.
  486. ;
  487. function Adjust_Size, $
  488.     Orig_Image       ; IN: original image   
  489.      
  490.     s = SIZE(Orig_Image)     
  491.              
  492.     if ((s(1) EQ 256) AND (s(2) EQ 256)) then begin
  493.         New_Image = Orig_Image     
  494.     endif else begin
  495.         New_Image = CONGRID (Orig_Image, 256, 256, /INTERP)     
  496.     endelse
  497.                      
  498.     RETURN, New_Image     
  499. end     
  500.  
  501. ;---------------------------------------------------------------------  
  502. ;
  503. ;   PURPOSE : Make the data to fall within a range
  504. ;
  505. function IN_RANGE, $
  506.     VALUE, $    ; IN: data
  507.     MINVAL, $   ; IN: minimum value
  508.     MAXVAL      ; IN: maximum value
  509.  
  510.     tmp = VALUE
  511.  
  512.     if (tmp LT MINVAL) then $
  513.         tmp = MINVAL $
  514.     ELSE if (tmp GT MAXVAL) then tmp = MAXVAL
  515.  
  516.     return, tmp
  517. end
  518.  
  519. ;---------------------------------------------------------------------  
  520. ;
  521. ;   PURPOSE :  This procedure clears the compressed image
  522. ;              and erase an image if appropriate.
  523. ;
  524. pro No_Compressed_Image, UVAL
  525.  
  526.     ;  This procedure clears the compressed image
  527.     ;  and erase an image if appropriate.
  528.     ;
  529.     if (UVAL.COMPRESSED EQ 1B) then begin
  530.     WSET, UVAL.ID_COMP
  531.     erase
  532.     ; do X plot
  533.     plots, [0,255],[0,255],/DEVICE
  534.     plots, [0,255],[255,0],/DEVICE
  535.     UVAL.COMP_IMG=0
  536.     empty
  537.         if NOT(Widget_Info(UVAL.WID_DIFFBASE, /Valid_Id)) then begin
  538.             B_DIFF = WIDGET_BASE(GROUP_LEADER=UVAL.WID_MAIN, $     
  539.                 COLUMN=1, MAP=0, $     
  540.                 TITLE='WaveletTool Image Differences')
  541.  
  542.                 D_DIFF = WIDGET_DRAW( B_DIFF, $     
  543.                     RETAIN=2, XSIZE=256, YSIZE=256, /FRAME)   
  544.  
  545.             WIDGET_CONTROL, B_DIFF, /Realize
  546.             WIDGET_CONTROL, D_DIFF, get_value=NEW_DIFF_ID
  547.             UVAL.ID_DIFF = NEW_DIFF_ID
  548.             UVAL.WID_DIFFBASE = B_DIFF
  549.         endif
  550.             WSET, UVAL.ID_DIFF
  551.         erase
  552.  
  553.         ; do X plot
  554.         plots, [0,255],[0,255],/DEVICE
  555.         plots, [0,255],[255,0],/DEVICE
  556.         empty
  557.         UVAL.COMPRESSED = 0B
  558.     endif    
  559. end
  560.  
  561. ;---------------------------------------------------------------------  
  562. ;
  563. ;   PURPOSE : Reset (empty) the drawing plots.
  564. ;
  565. pro Reset_Plot, $
  566.     UVAL    ; IN: uval structure
  567.  
  568.     ;  Reset plots.
  569.     ;
  570.     New_Percentage, UVAL, 0.0
  571.     Move_Line, UVAL, 0.0
  572. end
  573.  
  574. ;---------------------------------------------------------------------  
  575. ;
  576. ;   PURPOSE :  Refresh is set to 0/1 depending on whether we simply 
  577. ;              want to refresh the data in the plot.
  578. ;
  579. pro Percent_Plot, $
  580.     UVAL    ; IN: uval structure
  581.  
  582.     WSET, UVAL.ID_PLOT
  583.     plot_io, FINDGEN(1000)/10, UVAL.THRESHARRAY, $
  584.         ytitle='Threshold', $
  585.     Xtitle='% compression', YCHARSIZE=UVAL.CHARSIZE, $
  586.         XCHARSIZE=UVAL.CHARSIZE
  587. end
  588.  
  589. ;---------------------------------------------------------------------  
  590. ;
  591. ;   PURPOSE :  Update the compression plot.
  592. ;
  593. pro Update_Plot, $
  594.     UVAL    ; IN: uval structure
  595.  
  596.     ;  Refresh is set to 0/1 depending on whether we simply 
  597.     ;  want to refresh the data in the plot
  598.     ;
  599.     WSET, UVAL.ID_PLOT
  600.     PLOT_IO, FINDGEN(1000)/10, UVAL.THRESHARRAY, YTITLE='Threshold', $
  601.     XTITLE='% compression', $
  602.         /NOERASE, YCHARSIZE=UVAL.CHARSIZE, $
  603.         XCHARSIZE=UVAL.CHARSIZE
  604.  
  605. end
  606.  
  607. ;---------------------------------------------------------------------  
  608. ;
  609. ;   PURPOSE : Adjust the plot and slider to the new percentage value.
  610. ;
  611. pro New_Percentage, $
  612.     UVAL , $    ; IN: uval structure
  613.     PERCENT     ; IN: precentage value
  614.  
  615.     WIDGET_CONTROL,/hourglass
  616.     
  617.     ;  Send a 1 to move_line to refresh plot b/t draws.
  618.     ;
  619.     UVAL.PERCENTAGE = PERCENT
  620.  
  621.     ;  Get the appropriate threshold and save it
  622.     ;  (from the plotted dataset!).
  623.     ;
  624.     UVAL.THRESHOLD = UVAL.THRESHARRAY (UVAL.PERCENTAGE * 10)
  625.     Move_Slider, UVAL
  626.     textChange = ['void','comp1', 'comp2']
  627.     putTips, UVAL.sText, UVAL.wText[1], $
  628.         textChange, [0,1,2]
  629.     Update_Plot, UVAL        
  630.  
  631.     ;  Then it decimates and displays the new image 
  632.     ;  into the decimated wavelet draw widget.
  633.     ;
  634.     WSET, UVAL.ID_WAVE2
  635.     demo_wvlt_tv, CONGRID (Decimate(UVAL.WVLT_IMG, UVAL.THRESHOLD), 200, 200)
  636.     textChange = ['selecto','adjus', 'perce']
  637.     putTips, UVAL.sText, UVAL.wText[1], $
  638.         textChange, [0,1,2]
  639.  
  640. end
  641.  
  642. ;---------------------------------------------------------------------  
  643. ;
  644. ;   PURPOSE : Redraw the vertical line of the compression plot.
  645. ;
  646. pro Move_Line, $
  647.     UVAL , $    ; IN: uval structure
  648.     X           ; IN: precentage value
  649.  
  650.     ;  Expects X in DATA coordinates.
  651.     ;
  652.     WSET, UVAL.ID_PLOT
  653.     device, SET_GRAPHICS_FUNCTION=6
  654.     plots, [UVAL.PERCENTAGE, UVAL.PERCENTAGE],[1e-10, 1e+10], $
  655.         NOCLIP=0, /DATA, COLOR=200
  656.     empty
  657.     plots, [X,X],[1e-10, 1e+10], NOCLIP=0, /DATA, COLOR=200
  658.     device, SET_GRAPHICS_FUNCTION=3
  659.     xValue = STRING(UVAL.percentage, FORMAT='(f6.2)')
  660.     xValue = STRTRIM(xValue,2)
  661.     xValue = xValue + ' %'
  662.     WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE=xValue
  663.     empty
  664.  
  665. end
  666.  
  667. ;---------------------------------------------------------------------  
  668. ;
  669. ;   PURPOSE : Update the slider to the new percentage value.
  670. ;
  671. pro Move_Slider, $
  672.     UVAL     ; IN: uval structure
  673.  
  674.     WIDGET_CONTROL, UVAL.WID_SLIDER, SET_VALUE=UVAL.PERCENTAGE
  675. end
  676.  
  677. ;---------------------------------------------------------------------  
  678. ;
  679. ;   PURPOSE :  Redo plots with new image.
  680. ;
  681. PRO Got_New_Image, $
  682.     UVAL     ; IN: uval structure
  683.  
  684.     ;  Display it.     
  685.     ;
  686.     textChange = ['void','comp1', 'comp2']
  687.     putTips, UVAL.sText, UVAL.wText[1], $
  688.         textChange, [0,1,2]
  689.     WSET, UVAL.ID_ORIG     
  690.     TVSCL, UVAL.ORIG_IMG     
  691.  
  692.     ;  Get wavelet basis for this image     .
  693.     ;
  694.     Get_Wavelet_Basis, UVAL     
  695.     textChange = ['selecto','adjus', 'perce']
  696.     putTips, UVAL.sText, UVAL.wText[1], $
  697.         textChange, [0,1,2]
  698.     WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE=' 75.00%'
  699. end     
  700.      
  701. ;---------------------------------------------------------------------  
  702. ;
  703. ;   PURPOSE :  Redo plots with new image.
  704. ;
  705. pro Sensitize, $
  706.     UVAL, $     ; IN: uval structure
  707.     SENSE       ; IN: sensitive case (0 or 1)
  708.  
  709.     ;  Using ENABLE_WIDS, sensitize/desensitize
  710.     ;  the appropriate widgets.
  711.     ;
  712.     for i=0,(N_ELEMENTS(UVAL.ENABLE_WIDS)-1) do $
  713.         WIDGET_CONTROL, UVAL.ENABLE_WIDS(i), SENSITIVE=SENSE
  714. end     
  715.  
  716. ;---------------------------------------------------------------------  
  717. ;
  718. ;   PURPOSE : Change the top level base name to new file name.
  719. ;
  720. pro Change_Filename, $
  721.     UVAL, $     ; IN: uval structure
  722.     Filename    ; IN: file name (string)
  723.  
  724.     WIDGET_CONTROL, UVAL.WID_MAIN, $
  725.         TLB_SET_TITLE='WaveletTool - '+Filename
  726. end
  727.      
  728. ;---------------------------------------------------------------------  
  729. ;
  730. ;   PURPOSE : Erases original image draw widget.
  731. ;
  732. pro Erase_Original, $
  733.     UVAL     ; IN: uval structure
  734.  
  735.     WSET, UVAL.ID_ORIG
  736.     erase
  737. end     
  738.  
  739. ;---------------------------------------------------------------------  
  740. ;
  741. ;   PURPOSE : Erases original image draw widget.
  742. ;
  743. pro Erase_Secondary, $
  744.     UVAL     ; IN: uval structure
  745.  
  746.     WSET, UVAL.ID_WAVE1
  747.     erase
  748.     WSET, UVAL.ID_WAVE2
  749.     erase
  750.     WSET, UVAL.ID_PLOT
  751.     erase
  752.     No_Compressed_Image, UVAL
  753. end     
  754.      
  755. ;---------------------------------------------------------------------  
  756. ;
  757. ;   PURPOSE : Get a new data set.
  758. ;
  759. pro Data_Input, $
  760.     UVAL     ; IN: uval structure
  761.  
  762.     GetData2, NewImage, OFILENAME= file, /TWO_DIM, $
  763.         GROUP=UVAL.B_MAIN
  764.  
  765.     WIDGET_CONTROL,/hourglass            
  766.  
  767.     ;  If file is undefined, no selection     
  768.     ;
  769.     if (N_ELEMENTS(file) NE 0) then begin     
  770.  
  771.         ;  Got one, allow input to other widgets   
  772.         ;
  773.         Change_Filename, UVAL, file  
  774.  
  775.         ;  Adjust size of image to 256,256 if necessary     
  776.         ;
  777.         UVAL.ORIG_IMG = Adjust_Size (NewImage)
  778.         UVAL.FILE_LOADED = 1B
  779.         Sensitize, UVAL, 1
  780.         Erase_Original, UVAL
  781.         Erase_Secondary, UVAL
  782.         Got_New_Image, UVAL     
  783.         textChange = ['selecto','adjus', 'perce']
  784.         putTips, UVAL.sText, UVAL.wText[1], $
  785.             textChange, [0,1,2]
  786.  
  787.     endif     
  788. end     
  789.      
  790. ;---------------------------------------------------------------------  
  791. ;
  792. ;   PURPOSE : Given the wavelet basis and the setting
  793. ;             on the slider, do the compression and display it.
  794. ;
  795. pro Do_Compression, $
  796.     UVAL     ; IN: uval structure
  797.  
  798.     WIDGET_CONTROL, /HOURGLASS
  799.     WSET, UVAL.ID_COMP
  800.     erase
  801.     tmp = NR_WTN(DECIMATE (UVAL.WVLT_IMG, UVAL.THRESHOLD), $
  802.         UVAL.COEFFS, /INVERSE)
  803.  
  804.     ;  Range the value of the compressed image between 0 and 255.
  805.     ;
  806.     tmp = tmp > 0
  807.     tmp = tmp < 255
  808.  
  809.     UVAL.COMP_IMG = tmp
  810.     demo_wvlt_tv, tmp
  811.  
  812.     if (NOT(Widget_Info(UVAL.WID_DIFFBASE, /Valid_Id))) then begin
  813.         B_DIFF = WIDGET_BASE(GROUP_LEADER=UVAL.WID_MAIN, $     
  814.             COLUMN=1, MAP=0, $     
  815.             TITLE='WaveletTool Image Differences')
  816.  
  817.             D_DIFF = WIDGET_DRAW( B_DIFF, RETAIN=2, $     
  818.                 XSIZE=256, YSIZE=256, /FRAME)   
  819.  
  820.         WIDGET_CONTROL, B_DIFF, /Realize
  821.         WIDGET_CONTROL, D_DIFF, get_value=NEW_DIFF_ID
  822.         UVAL.ID_DIFF = NEW_DIFF_ID
  823.         UVAL.WID_DIFFBASE = B_DIFF
  824.     endif
  825.  
  826.     WSET, UVAL.ID_DIFF
  827.     erase
  828.     UVAL.differenceImage = bytscl((UVAL.ORIG_IMG - tmp) > 0, $
  829.        top=!d.table_size-1)
  830.     UVAL.compressImageFlag = 1
  831.     demo_wvlt_tv, UVAL.differenceImage
  832.     UVAL.COMPRESSED = 1B
  833. end     
  834.  
  835. ;---------------------------------------------------------------------  
  836. ;
  837. ;   PURPOSE : Get a new wavelet basis, clear the draw window,
  838. ;             recompute the new image (do compresssion) and
  839. ;             display that image.
  840. ;
  841. pro New_Coeff, $
  842.     UVAL, $     ; IN: uval structure
  843.     COEFF       ; IN: wavelet coeeficients
  844.  
  845.     if (COEFF NE UVAL.COEFFS) then begin
  846.         UVAL.COEFFS = COEFF
  847.  
  848.         if (UVAL.FILE_LOADED EQ 1B) then begin
  849.             textChange = ['void','comp1', 'comp2']
  850.             putTips, UVAL.sText, UVAL.wText[1], $
  851.                 textChange, [0,1,2]
  852.             Erase_Secondary, UVAL
  853.         Get_Wavelet_Basis, UVAL     
  854.             textChange = ['selecto','adjus', 'perce']
  855.             putTips, UVAL.sText, UVAL.wText[1], $
  856.                 textChange, [0,1,2]
  857.     endif      
  858.     endif
  859. end
  860.      
  861. ;---------------------------------------------------------------------  
  862. ;
  863. ;   PURPOSE : Save the compressed image.
  864. ;
  865. ;pro Do_Save, $
  866. ;    UVAL     ; IN: uval structure
  867. ;
  868. ;    file = PICKFILE(/WRITE, FILTER='*.dat', GROUP=UVAL.WID_MAIN)
  869. ;    if (file NE '')  then begin
  870. ;
  871. ;        ;  Only write if a file was selected.
  872. ;        ;
  873. ;        openw, unit, /GET_LUN, file, /XDR
  874. ;        writeu, unit, UVAL.COMP_IMG
  875. ;        free_lun, unit
  876. ;    endif
  877. ;end
  878. ;
  879. ;---------------------------------------------------------------------  
  880. ;
  881. ;   PURPOSE : Main event handler.
  882. ;
  883. pro WaveletTool_Event, $
  884.     Event               ; IN: event structure     
  885.      
  886.     if (TAG_NAMES(Event, /STRUCTURE_NAME) EQ $
  887.         'WIDGET_KILL_REQUEST') then begin
  888.         WIDGET_CONTROL, Event.top, /DESTROY
  889.         RETURN
  890.     endif
  891.  
  892.     WIDGET_CONTROL,Event.Id,GET_UVALUE=WidUvalue
  893.     WIDGET_CONTROL,Event.Top, GET_UVALUE=UVAL, /NO_COPY     
  894.        
  895.     case WidUvalue of      
  896.  
  897.         ;  Open a new file (new data set).
  898.         ;
  899.         'OPEN': begin
  900.             Data_Input, UVAL    
  901.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=0
  902.             UVAL.compressImageFlag = 0
  903.  
  904.             perc = 75L
  905.             Move_Line, UVAL, perc
  906.             New_Percentage, UVAL, perc
  907.             xValue = STRING(perc, FORMAT='(f6.2)')
  908.             xValue = STRTRIM(xValue,2)
  909.             xValue = xValue + ' %'
  910.             WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE=xValue
  911.             Do_Compression, UVAL     
  912.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  913.  
  914.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  915.  
  916.         end
  917.  
  918.         ;  Quit this application.
  919.         ;
  920.         'QUIT': begin
  921.             WIDGET_CONTROL,Event.Top, SET_UVALUE=UVAL, /NO_COPY     
  922.             WIDGET_CONTROL,Event.Top, /destroy     
  923.  
  924.             ;  Return after this!     
  925.             ;
  926.             return     
  927.         end
  928.                             
  929.         ;  Compute the wavelet transform with 4 coefficients.
  930.         ;
  931.         'FOUR': begin
  932.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=0
  933.             WIDGET_CONTROL, UVAL.wFourButton, SENSITIVE=0
  934.             WIDGET_CONTROL, UVAL.wTwelveButton, SENSITIVE=1
  935.             WIDGET_CONTROL, UVAL.wTwentyButton, SENSITIVE=1
  936.             New_Coeff, UVAL, 4
  937.             Do_Compression, UVAL     
  938.             WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE='000.00%'
  939.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  940.         end
  941.                         
  942.         ;  Compute the wavelet transform with 12 coefficients.
  943.         ;
  944.         'TWELVE': begin
  945.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=0
  946.             WIDGET_CONTROL, UVAL.wFourButton, SENSITIVE=1
  947.             WIDGET_CONTROL, UVAL.wTwelveButton, SENSITIVE=0
  948.             WIDGET_CONTROL, UVAL.wTwentyButton, SENSITIVE=1
  949.             New_Coeff, UVAL, 12
  950.             WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE='000.00%'
  951.             Do_Compression, UVAL     
  952.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  953.         end
  954.                                 
  955.         ;  Compute the wavelet transform with 20 coefficients.
  956.         ;
  957.         'TWENTY': begin
  958.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=0
  959.             WIDGET_CONTROL, UVAL.wFourButton, SENSITIVE=1
  960.             WIDGET_CONTROL, UVAL.wTwelveButton, SENSITIVE=1
  961.             WIDGET_CONTROL, UVAL.wTwentyButton, SENSITIVE=0
  962.             New_Coeff, UVAL, 20
  963.             Do_Compression, UVAL     
  964.             WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE='000.00%'
  965.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  966.         end
  967.                                 
  968.         ;  Show the difference between the original and the
  969.         ;  compressed image.
  970.         ;
  971.         'DIFFERENCE': begin
  972.             if (UVAL.compressImageFlag eq 1) then begin
  973.                 if not(Widget_Info(UVAL.WID_DIFFBASE, $
  974.                     /Valid_Id)) then begin
  975.  
  976.                     B_DIFF = WIDGET_BASE(GROUP_LEADER= $
  977.                         UVAL.WID_MAIN, $     
  978.                         COLUMN=1, MAP=0, $     
  979.                         TITLE='WaveletTool Image Differences')
  980.  
  981.                     D_DIFF = WIDGET_DRAW( B_DIFF, $     
  982.                         RETAIN=2, XSIZE=256, YSIZE=256, /FRAME)   
  983.  
  984.                     WIDGET_CONTROL, B_DIFF, /REALIZE
  985.                     WIDGET_CONTROL, D_DIFF, get_value=NEW_DIFF_ID
  986.                     UVAL.ID_DIFF = NEW_DIFF_ID
  987.                     UVAL.WID_DIFFBASE = B_DIFF
  988.                     WSET, NEW_DIFF_ID
  989.                     demo_wvlt_tv, UVAL.differenceImage
  990.                 endif
  991.  
  992.                 ;  Map the showdiff base
  993.                 ;
  994.                 WIDGET_CONTROL, UVAL.WID_DIFFBASE, MAP=1
  995.                 WIDGET_CONTROL, UVAL.WID_DIFFBASE, /SHOW
  996.             endif
  997.         end    
  998.                             
  999.         ;  Load a new color table.
  1000.         ;
  1001.         'XLOADCT': begin
  1002.             WIDGET_CONTROL,Event.Top, SET_UVALUE=UVAL, /NO_COPY     
  1003.             WIDGET_CONTROL,/hourglass
  1004.             XLoadct, GROUP=Event.top
  1005.             RETURN
  1006.         end
  1007.                                 
  1008.         ;  Display the information text.
  1009.         ;
  1010.         'ABOUT': begin 
  1011.             if (Xregistered('XDisplayFile') ne 0) then begin
  1012.                 WIDGET_CONTROL,Event.Top, SET_UVALUE=UVAL, /NO_COPY     
  1013.                 RETURN
  1014.             endif
  1015.  
  1016.             ;  Display the information.
  1017.             ;
  1018.             XDisplayFile, filepath("wavelet.txt", $
  1019.                 SUBDIR=['examples','demo','demotext']), $
  1020.                 DONE_BUTTON='Done', $
  1021.                 TITLE="Wavelet tool help", $
  1022.                 GROUP=Event.top, WIDTH=55, HEIGHT=14
  1023.         end    ;   of ABOUT
  1024.  
  1025.  
  1026.                      
  1027.         ;  Handle the compression slider event. Redo all the plots.
  1028.         ;
  1029.         'S_COMPRESSED': begin     
  1030.  
  1031.             ;  Need to clear the comp image draw
  1032.             ;  we are guarranteed no drag events
  1033.             ;
  1034.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=0
  1035.             Move_Line, UVAL, Event.value
  1036.             New_Percentage, UVAL, Event.value
  1037.             xValue = STRING(Event.value, FORMAT='(f6.2)')
  1038.             xValue = STRTRIM(xValue,2)
  1039.             xValue = xValue + ' %'
  1040.             WIDGET_CONTROL, UVAL.SliderValue, SET_VALUE=xValue
  1041.             Do_Compression, UVAL     
  1042.             WIDGET_CONTROL, UVAL.B_MAIN, SENSITIVE=1
  1043.         END          
  1044.  
  1045.         ;  Handle the compression plot drawing event.
  1046.         ;
  1047.         'D_PLOT': begin     
  1048.  
  1049.             CASE Event.Type of
  1050.  
  1051.                 0: begin
  1052.  
  1053.                     ;  Button press
  1054.                     ;  check which button (only left buttton is active)
  1055.                     ;
  1056.                     if (Event.Press EQ 1) then begin
  1057.  
  1058.                         ;  Start the drag process
  1059.                         ;
  1060.                         UVAL.DRAGGING = 1B
  1061.  
  1062.                         ;  Draw the first line
  1063.                         ;
  1064.                         WSET, UVAL.ID_PLOT
  1065.                         tmp = Convert_coord(Event.X,0,/device,/to_data)
  1066.                         tmp(0)= IN_RANGE (tmp(0), 0, 100)
  1067.                         Move_Line, UVAL, tmp(0)
  1068.                         UVAL.PERCENTAGE = tmp(0)
  1069.                     endif
  1070.                 END                   ;   of 0
  1071.                             
  1072.                 1: begin
  1073.  
  1074.                     ;  Button release
  1075.                     ;  check which button (only act on left)
  1076.                     ;
  1077.                     if (Event.Release EQ 1) then begin
  1078.  
  1079.                         ;  Stop the dragging
  1080.                         ;
  1081.                         UVAL.DRAGGING = 0B
  1082.  
  1083.                         ;  Evaluate percentage and update slider, etc.
  1084.                         ;  need to clear the comp image draw
  1085.                         ;
  1086.                         WSET, UVAL.ID_PLOT
  1087.                         tmp = Convert_coord(Event.X,0,/device,/to_data)
  1088.                         tmp(0)= IN_RANGE (tmp(0), 0, 100)
  1089.                         Move_Line, UVAL, tmp(0)
  1090.                         New_Percentage, UVAL, tmp(0)
  1091.                         Do_Compression, UVAL     
  1092.                     endif
  1093.                 END                   ;   of 1
  1094.                             
  1095.                 2: begin
  1096.  
  1097.                     ;  Motion event.
  1098.                     ;  Check if dragging.
  1099.                     ;
  1100.                     if (UVAL.DRAGGING EQ 1B) then begin
  1101.  
  1102.                         ;  Draw new line (xor'd)
  1103.                         ;
  1104.                         WSET, UVAL.ID_PLOT
  1105.                         tmp = Convert_coord(Event.X,0,/device,/to_data)
  1106.                         tmp(0)= IN_RANGE (tmp(0), 0, 100)
  1107.                         Move_Line, UVAL, tmp(0)
  1108.                         UVAL.PERCENTAGE=tmp(0)
  1109.                     endif
  1110.                 END            ;   of 2
  1111.                             
  1112.                 ELSE:
  1113.  
  1114.             endcase
  1115.         END          
  1116.                      
  1117.         ELSE:      ;   do nothing
  1118.                      
  1119.     endcase     
  1120.              
  1121.     WIDGET_CONTROL, Event.Top, SET_UVALUE=UVAL, /NO_COPY     
  1122.      
  1123. end    
  1124.  
  1125. ;---------------------------------------------------------------------  
  1126. ;
  1127. ;   PURPOSE : Cleanup procedure.
  1128. ;
  1129. pro Wavelet_Cleanup, tlb
  1130.  
  1131.     ;  Get the color table saved in the window's user value.
  1132.     ;
  1133.     WIDGET_CONTROL, tlb, GET_UVALUE=UVAL, /NO_COPY
  1134.  
  1135.     ;  Restore the previous color table.
  1136.     ;
  1137.     TVLCT, UVAL.colorTable
  1138.  
  1139.     if widget_info(UVAL.groupBase, /valid) then $
  1140.         WIDGET_CONTROL, UVAL.groupBase, /map
  1141.  
  1142. end  ; Of Wavelet_Cleanup
  1143.      
  1144. ;---------------------------------------------------------------------  
  1145. ;
  1146. ;   PURPOSE :  Transform an image using the orthogonal
  1147. ;              wavelet method (Daubechies coefficients).
  1148. ;
  1149. pro D_Wavelet, $
  1150.     GROUP=group, $     ; IN: (opt) group identifier
  1151.     APPTLB = appTLB    ; OUT: (opt) TLB of this application
  1152.  
  1153.     ;  Check the validity of the group identifier.
  1154.     ;
  1155.     ngroup = N_ELEMENTS(group)
  1156.     if (ngroup NE 0) then begin
  1157.         check = widget_INFO(group, /valid)
  1158.         if (check NE 1) then begin
  1159.             print,'Error, the group identifier is not valid'
  1160.             print, 'Return to the main application'
  1161.             RETURN
  1162.         endif
  1163.         groupBase = group
  1164.     endif else groupBase = 0L
  1165.  
  1166.      
  1167.     CHARSIZE = 6.0 / !D.X_CH_SIZE
  1168.  
  1169.     ;  Get the screeen size.
  1170.     ;
  1171.     device, GET_SCREEN_SIZE=scr
  1172.  
  1173.     myScroll = 0   ; For adding scroll bars if necessary
  1174.     if (scr(0) LT 1000) then begin
  1175.         void =  $
  1176.         WIDGET_MESSAGE('This application is optimized for 1024 x 768 resolution') 
  1177.         myScroll = 1  ; Add the scroll bar when creating the TLB
  1178.     endif
  1179.  
  1180.  
  1181.     ;  Get the screen size and set an offset..
  1182.     ;
  1183.     Device, GET_SCREEN_SIZE = scrsize
  1184.  
  1185.     ;  Create the starting up message.
  1186.     ;
  1187.     if (ngroup EQ 0) then begin
  1188.         drawbase = startmes()
  1189.     endif else begin
  1190.         drawbase = startmes(GROUP=group)
  1191.     endelse
  1192.  
  1193.     xdimImage = 256
  1194.     ydimImage = 256
  1195.     xdimBasis = 256
  1196.     ydimBasis = 256
  1197.     xdimPlot = 256
  1198.     ydimPlot = 256
  1199.  
  1200.     ;  Save the current color table.
  1201.     ;
  1202.     TVLCT, savedR, savedG, savedB,/GET
  1203.     colorTable=[[savedR], [savedG], [savedB]]
  1204.  
  1205.     ;  Load an new color table.
  1206.     ;
  1207.     LOADCT, 0
  1208.  
  1209.     junk   = { CW_PDMENU_S, flags:0, name:'' }     
  1210.  
  1211.     ;  Get the tips.
  1212.     ;
  1213.     sText = getTips(filepath('wavelet.tip', $
  1214.         SUBDIR=['examples','demo', 'demotext']) )
  1215.                               
  1216.     ;  Create the widget hierarchy starting with the
  1217.     ;  top level base.
  1218.     ;
  1219.     if (myScroll EQ 1) then begin
  1220.         if (N_ELEMENTS(group) EQ 0) then begin
  1221.             B_MAIN = WIDGET_BASE( $
  1222.                 TLB_FRAME_ATTR=1, $
  1223.                 SCROLL=myScroll, $
  1224.                 X_SCROLL_SIZE=scrsize[0]-75, Y_SCROLL_SIZE=scrsize[1]-75, $
  1225.                 /TLB_KILL_REQUEST_EVENTS, $
  1226.                 COLUMN=1, MAP=0, MBAR=barBase, TITLE='WaveletTool')     
  1227.         endif else begin
  1228.             B_MAIN = WIDGET_BASE(GROUP_LEADER=group, $     
  1229.                 TLB_FRAME_ATTR=1, $
  1230.                 SCROLL=myScroll, $
  1231.                 X_SCROLL_SIZE=scrsize[0]-75, Y_SCROLL_SIZE=scrsize[1]-75, $
  1232.                 /TLB_KILL_REQUEST_EVENTS, $
  1233.                 COLUMN=1, MAP=0, MBAR=barBase, TITLE='WaveletTool')     
  1234.         endelse
  1235.     endif else begin
  1236.         if (N_ELEMENTS(group) EQ 0) then begin
  1237.             B_MAIN = WIDGET_BASE( $
  1238.                 TLB_FRAME_ATTR=1, $
  1239.                 /TLB_KILL_REQUEST_EVENTS, $
  1240.                 COLUMN=1, MAP=0, MBAR=barBase, TITLE='WaveletTool')     
  1241.         endif else begin
  1242.             B_MAIN = WIDGET_BASE(GROUP_LEADER=group, $     
  1243.                 TLB_FRAME_ATTR=1, $
  1244.                 /TLB_KILL_REQUEST_EVENTS, $
  1245.                 COLUMN=1, MAP=0, MBAR=barBase, TITLE='WaveletTool')     
  1246.         endelse
  1247.     endelse
  1248.  
  1249.         ;  Create the file menu.
  1250.         ;
  1251.         wFileButton = WIDGET_BUTTON(barbase, VALUE='File', /MENU)
  1252.  
  1253.             wOpenButton = WIDGET_BUTTON(wFileButton, $
  1254.                 VALUE='Open', UVALUE='OPEN')
  1255.  
  1256.             wQuitButton = WIDGET_BUTTON(wFileButton, $
  1257.                 VALUE='Quit', UVALUE='QUIT')
  1258.  
  1259.         ;  Create the option menu.
  1260.         ;
  1261.         wOptionButton = WIDGET_BUTTON(barbase, VALUE='Options', /MENU)
  1262.  
  1263.             wFourButton = WIDGET_BUTTON(wOptionButton, $
  1264.                 VALUE='4 Coefficients', UVALUE='FOUR')
  1265.  
  1266.             wTwelveButton = WIDGET_BUTTON(wOptionButton, $
  1267.                 VALUE='12 Coefficients', UVALUE='TWELVE')
  1268.  
  1269.             wTwentyButton = WIDGET_BUTTON(wOptionButton, $
  1270.                 VALUE='20 Coefficients', UVALUE='TWENTY')
  1271.  
  1272.             wDifferenceButton = WIDGET_BUTTON(wOptionButton, $
  1273.                 VALUE='Show Difference Image', UVALUE='DIFFERENCE')
  1274.  
  1275.         ;  Create the tool menu.
  1276.         ;
  1277.         wViewButton = WIDGET_BUTTON(barbase, VALUE='View', /MENU)
  1278.  
  1279.             wXLoadctButton = WIDGET_BUTTON(wViewButton, $
  1280.                 VALUE='Color Palette', UVALUE='XLOADCT')
  1281.  
  1282.         ;  Create the Help/About button.
  1283.         ;
  1284.         wHelpButton = WIDGET_BUTTON(barbase, /HELP, Value = 'About',/Menu)
  1285.  
  1286.             wAboutButton = WIDGET_BUTTON(wHelpButton, $
  1287.                 VALUE='About Wavelets', UVALUE='ABOUT')
  1288.  
  1289.         B_ALLDISP = WIDGET_BASE(B_MAIN, ROW=1, SPACE=5, XPAD=5, YPAD=5, $     
  1290.             FRAME=1, MAP=1, TITLE='ALL Display', UVALUE='B_ALLDISP')     
  1291.                                          
  1292.             ;  B_DISPLAY is the base that contains the original 
  1293.             ;  and compressed images.
  1294.             ;
  1295.             B_DISPLAY = WIDGET_BASE(B_ALLDISP, /COLUMN, SPACE=5, $     
  1296.             XPAD=5, YPAD=5, FRAME=1, MAP=1, TITLE='Display', $     
  1297.                 UVALUE='B_DISPLAY', /BASE_ALIGN_CENTER)     
  1298.      
  1299.                 B_ORIGINAL = WIDGET_BASE(B_DISPLAY, COLUMN=1, MAP=1, $     
  1300.                     TITLE='original_base', UVALUE='B_ORIGINAL')     
  1301.      
  1302.                     L_ORIGINAL = WIDGET_LABEL( B_ORIGINAL, $     
  1303.                         UVALUE='L_ORIGINAL', VALUE='Original:')     
  1304.      
  1305.                     D_ORIGINAL = WIDGET_DRAW( B_ORIGINAL, $     
  1306.                         RETAIN=2, UVALUE='D_ORIGINAL', $     
  1307.                         XSIZE=256, YSIZE=256, /FRAME)     
  1308.      
  1309.                 B_COMPRESSED = WIDGET_BASE(B_DISPLAY, COLUMN=1, $     
  1310.                     MAP=1, TITLE='compressed_base', $     
  1311.                     UVALUE='B_COMPRESSED')     
  1312.      
  1313.                     L_COMPRESSED = WIDGET_LABEL( B_COMPRESSED, $     
  1314.                         UVALUE='L_COMPRESSED', VALUE='Compressed:')     
  1315.      
  1316.                     D_COMPRESSED = WIDGET_DRAW( B_COMPRESSED, $     
  1317.                         RETAIN=2, UVALUE='D_COMPRESSED', $     
  1318.                         XSIZE=256, YSIZE=256, /FRAME)     
  1319.  
  1320.             ;  B_WAVEADJ is the base that contains our interface 
  1321.             ;  to adjust the compression amount of our wavelet basis.
  1322.             ;
  1323.             B_WAVES = WIDGET_BASE(B_ALLDISP, COLUMN=1, SPACE=5, $     
  1324.                 XPAD=5, YPAD=5, FRAME=1, MAP=1, $     
  1325.                 TITLE='Wavelets', UVALUE='B_WAVES')     
  1326.                                  
  1327.                 L_WAVES = WIDGET_LABEL( B_WAVES, $     
  1328.                     UVALUE='L_WAVES', VALUE='Wavelet Basis:')     
  1329.      
  1330.                 B_WAVEADJ = WIDGET_BASE(B_WAVES, ROW=1, SPACE=10, $     
  1331.                     XPAD=10, YPAD=10, FRAME=0, MAP=1, $     
  1332.                     TITLE='Wavelet Adjust', UVALUE='B_WAVEADJ')     
  1333.                                  
  1334.                     ;  Base to hold tv's of wavelet basis.
  1335.                     ;
  1336.                     B_SHOWIMAGE1 = WIDGET_BASE(B_WAVEADJ, $     
  1337.                         /COLUMN, MAP=1, TITLE='show wavelet images', $     
  1338.                         UVALUE='B_SHOWIMAGE1')     
  1339.  
  1340.                         L_WAVE1 = WIDGET_LABEL( B_SHOWIMAGE1, $     
  1341.                             UVALUE='L_WAVE1', VALUE='Original:')     
  1342.                          
  1343.                         D_WAVE1 = WIDGET_DRAW( B_SHOWIMAGE1, $     
  1344.                             RETAIN=2, UVALUE='D_WAVE1', $
  1345.                             XSIZE=200, YSIZE=200, /FRAME)
  1346.  
  1347.                     B_SHOWIMAGE2 = WIDGET_BASE(B_WAVEADJ, $     
  1348.                         /COLUMN, MAP=1, TITLE='show wavelet images', $     
  1349.                         UVALUE='B_SHOWIMAGE2')     
  1350.  
  1351.                         L_WAVE2 = WIDGET_LABEL( B_SHOWIMAGE2, $     
  1352.                             UVALUE='L_WAVE2', VALUE='Compressed:')     
  1353.  
  1354.                         D_WAVE2 = WIDGET_DRAW( B_SHOWIMAGE2, $     
  1355.                             RETAIN=2, UVALUE='D_WAVE2', $     
  1356.                             XSIZE=200, YSIZE=200, /FRAME)
  1357.  
  1358.                 ;  Base to hold plot and slider for adjusting compression.
  1359.                 ;
  1360.                 B_ADJCOMP = WIDGET_BASE(B_WAVES, $     
  1361.                     COLUMN=1, MAP=1, FRAME=0, SPACE=10, $     
  1362.                     XPAD=10, YPAD=10, TITLE='adjust compression', $     
  1363.                     UVALUE='B_ADJCOMP')     
  1364.                                                  
  1365.                     L_ADJCOMP = WIDGET_LABEL( B_ADJCOMP, $     
  1366.                         UVALUE='L_ADJCOMP', VALUE='Adjust Compression:')     
  1367.  
  1368.                     D_PLOT = WIDGET_DRAW( B_ADJCOMP, RETAIN=2, $     
  1369.                         UVALUE='D_PLOT', $     
  1370.                         XSIZE=420, YSIZE=200, /FRAME, $
  1371.                         /MOTION_EVENTS, /BUTTON_EVENTS)     
  1372.  
  1373.                     SliderValue = WIDGET_LABEL(B_ADJCOMP, $ 
  1374.                         VALUE='  75.00 %', /ALIGN_CENTER)
  1375.  
  1376.                     S_COMPRESSED = WIDGET_SLIDER( B_ADJCOMP, $     
  1377.                         MAXIMUM=100, XSIZE=420, $
  1378.                         TITLE='Percentage Compression', $     
  1379.                         UVALUE='S_COMPRESSED', $     
  1380.             VALUE=75, /SUPPRESS_VALUE)
  1381.  
  1382.         ;  Create the status line label.
  1383.         ;
  1384.         wStatusBase = WIDGET_BASE(B_MAIN, MAP=0, /ROW)
  1385.  
  1386.             nWidgets = 2
  1387.             wText = LONARR(nWidgets)
  1388.             widTips, wStatusBase, sText.text, XSIZE=36, $
  1389.                 YSIZE=3, NWIDGETS=nWidgets, wText
  1390.  
  1391.         ;  We have a second top-level base to show differences.
  1392.         ;
  1393.         B_DIFF = WIDGET_BASE(GROUP_LEADER=B_MAIN, COLUMN=1, $     
  1394.             MAP=0, TITLE='WaveletTool Image Differences')
  1395.      
  1396.             D_DIFF = WIDGET_DRAW( B_DIFF, RETAIN=2, $     
  1397.             XSIZE=256, YSIZE=256, /FRAME)   
  1398.             
  1399.     WIDGET_CONTROL, B_MAIN, /REALIZE     
  1400.     WIDGET_CONTROL, B_DIFF, MAP=0, /REALIZE
  1401.  
  1402.     ; Returns the top level base to the APPTLB keyword.
  1403.     ;
  1404.     appTLB = B_MAIN
  1405.  
  1406.     ;  Size the tips widgets.
  1407.     ;
  1408.     sizeTips, B_MAIN, wText, wStatusBase
  1409.  
  1410.  
  1411.     UVAL = {ID_ORIG:0L, $                ; Windows IDs, original
  1412.             ID_COMP:0L, $                ;              compressed 
  1413.             ID_WAVE1:0L, $               ;              wavelet 1
  1414.             ID_WAVE2:0L, $               ;              wavelet 2
  1415.             ID_PLOT:0L, $                ;              pecentage plot
  1416.             ID_DIFF:0L, $                ;              difference image
  1417.             B_MAIN: B_MAIN, $            ; Top level base
  1418.             WID_STATUS:0L, $             ; Status label ID
  1419.             WID_SLIDER:0L, $             ; Percentage slider ID
  1420.             WID_DIFFBASE:0L, $           ; Difference image base ID
  1421.             WID_MAIN:0L, $               ; Main base ID
  1422.             WID_COEFFS:0L, $             ; Number of coefficients button IDs
  1423.             ENABLE_WIDS:LONARR(8), $     ; Enabled widgets IDs (see list below)
  1424.             THRESHOLD: 0.0, $            ; Threshold value
  1425.             COEFFS:0, $                  ; Number of wavelets coefficients
  1426.             FILE_LOADED:0B, $            ; File loaded flag
  1427.             PERCENTAGE:0.0, $            ; Compression precentage value
  1428.             DRAGGING:0B, $               ; Dragging mode:0=not, 1=yes
  1429.             WFourButton: wFourButton, $  ; Widget button IDs
  1430.             WTwelveButton: wTwelveButton, $
  1431.             WTwentyButton: wTwentyButton, $
  1432.             DifferenceImage:  $
  1433.             BYTARR(xdimImage, yDimImage), $ ; Difference image
  1434.             SliderValue: SliderValue, $  ; Percentage slider value
  1435.             CompressImageFlag : 0, $     ; 0= not drawn, 1=drawn
  1436.             ColorTable: colorTable, $    ; Color table to restore
  1437.             CHARSIZE: CHARSIZE, $
  1438.             WText: wText, $              ; Widget text IDs for tips
  1439.             SText: sText, $              ; Text structure for tips
  1440.             ;  Set this to 1 to start to force erase of ID_COMP
  1441.             COMPRESSED:1B, $             ; Compress flag
  1442.             THRESHARRAY:FLTARR(1001), $  ; Threshold array
  1443.             ORIG_IMG:BYTARR(256,256), $  ; Original image
  1444.             WVLT_IMG:FLTARR(256,256), $  ; Wavelet image
  1445.             COMP_IMG:BYTARR(256,256), $  ; Compressed image
  1446.             groupBase: groupBase $       ; Base of Group Leader
  1447.     }
  1448.                 
  1449.  
  1450.     ;  The ENABLE_WIDS array is an array of widget ids 
  1451.     ;  to desensitize when there
  1452.     ;  is no filename selected.
  1453.      
  1454.     ;  Fill the UVALUE structure of our main base with our values.
  1455.     ;
  1456.     WIDGET_CONTROL, D_ORIGINAL, GET_VALUE=originalValue
  1457.     UVAL.ID_ORIG = originalValue     
  1458.     WIDGET_CONTROL, D_COMPRESSED, GET_VALUE=compressedValue
  1459.     UVAL.ID_COMP = compressedValue   
  1460.     WIDGET_CONTROL, D_WAVE1, GET_VALUE=wave1Value     
  1461.     UVAL.ID_WAVE1 = wave1Value
  1462.     WIDGET_CONTROL, D_WAVE2, GET_VALUE=wave2Value     
  1463.     UVAL.ID_WAVE2 = wave2Value
  1464.     WIDGET_CONTROL, D_PLOT, GET_VALUE=differenceValue     
  1465.     UVAL.ID_PLOT = differenceValue
  1466.     WIDGET_CONTROL, D_DIFF, GET_VALUE=differenceValue     
  1467.     UVAL.ID_DIFF = differenceValue
  1468.     UVAL.WID_SLIDER = S_COMPRESSED        
  1469.     UVAL.WID_DIFFBASE = B_DIFF
  1470.     UVAL.WID_MAIN = B_MAIN
  1471.     UVAL.ENABLE_WIDS = $
  1472.         [L_COMPRESSED, L_WAVE1, L_WAVE2, L_ADJCOMP, L_ORIGINAL, $
  1473.     L_WAVES, S_COMPRESSED, D_PLOT]
  1474.     
  1475.     ;  Set up initial parameters.
  1476.     ;  Clean up the windows.
  1477.     ;
  1478.     New_Coeff, UVAL, 4
  1479.     Erase_Original, UVAL
  1480.     Erase_Secondary, UVAL
  1481.     Sensitize, UVAL, 0
  1482.     textChange = ['sele1', 'sele2']
  1483.     putTips, UVAL.sText, UVAL.wText[1], $
  1484.         textChange, [1,2]
  1485.     Change_Filename, UVAL, '<NONE>'
  1486.         
  1487.  
  1488.     ;  Load an initial file .
  1489.     ;
  1490.     file = 'ctscan.dat'
  1491.     GetData2, NewImage, FILENAME=file, /TWO_DIM     
  1492.     Change_Filename, UVAL, file
  1493.  
  1494.     ;  Adjust size of image to 256,256 if necessary.
  1495.     ;
  1496.     UVAL.ORIG_IMG = Adjust_Size (NewImage)
  1497.     UVAL.FILE_LOADED = 1B
  1498.     Sensitize, UVAL, 1
  1499.     Erase_Original, UVAL
  1500.     Erase_Secondary, UVAL
  1501.     Got_New_Image, UVAL
  1502.     textChange = ['selecto','adjus', 'perce']
  1503.     putTips, UVAL.sText, UVAL.wText[1], $
  1504.         textChange, [0,1,2]
  1505.  
  1506.     WIDGET_CONTROL, B_MAIN, SET_UVALUE=UVAL      
  1507.     WIDGET_CONTROL, wFourButton, SENSITIVE=0
  1508.       
  1509.     ;  Destroy the starting up window.
  1510.     ;
  1511.     WIDGET_CONTROL, drawbase, /DESTROY
  1512.  
  1513.     ;  Map the top level base.
  1514.     ;
  1515.     WIDGET_CONTROL, B_MAIN, MAP=1
  1516.  
  1517.     ;  Set up the default percentage value to 75 %.
  1518.     ;
  1519.     pseudoEvent = { $
  1520.         ID: S_COMPRESSED, $
  1521.         TOP: B_MAIN, $
  1522.         HANDLER: B_MAIN, $
  1523.         VALUE:75L, $
  1524.         DRAG:0 $
  1525.     }
  1526.     WaveletTool_Event, pseudoEvent
  1527.  
  1528.     ;  Map the top level base.
  1529.     ;
  1530.     WIDGET_CONTROL, B_MAIN, MAP=1
  1531.  
  1532.     XMANAGER, 'D_Wavelet', B_MAIN, $
  1533.         EVENT_HANDLER='WaveletTool_Event', CLEANUP='Wavelet_Cleanup', $
  1534.         /NO_BLOCK
  1535.  
  1536. end  ;    of d_wavelet     
  1537.